package com.dingreading.cloud.admin.controller;

import com.dingreading.cloud.admin.dto.ShopCartCheckDto;
import com.dingreading.cloud.admin.entity.*;
import com.dingreading.cloud.admin.feign.PayOkFeignService;
import com.dingreading.cloud.admin.service.*;
import com.dingreading.cloud.admin.util.ShopCartUtilV2;
import com.dingreading.cloud.admin.util.bean.OrderFormV3Util;
import com.dingreading.cloud.admin.util.redis.RedisService;
import com.dingreading.cloud.common.base.R;
import com.dingreading.cloud.common.util.*;
import com.dingreading.cloud.common.util.qyweixin.AccessTokenDto;
import com.dingreading.cloud.common.util.qyweixin.QyWeiXinUtil;
import com.dingreading.cloud.common.util.qyweixin.QyWeixinMsg;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Table;
import io.seata.spring.annotation.GlobalTransactional;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@RefreshScope
@RestController
@RequestMapping(value = "/system/orderFormGive/v3")
@Api(tags = "总部-商城赠品订单管理")
public class OrderFormGiveControllerV3 {

    @Value("${serverUrl}")
    private String serverUrl;

    @Value("${qyweixin.corpid}")
    private String corpid;
    @Value("${qyweixin.secret}")
    private String secret;
    @Value("${qyweixin.agentid}")
    private String agentid;
    @Value("${qyweixin.managerUserid}")
    private String managerUserid;
    @Value("${qyweixin.subManagerUserid}")
    private String subManagerUserid;

    @Resource
    protected StoresService storesService;
    @Resource
    protected StaffService staffService;
    @Resource
    protected DeliveryAddressService deliveryAddressService;
    @Resource
    protected ShopCartService shopCartService;
    @Resource
    protected GoodsService goodsService;
    @Resource
    protected GoodsTypeService goodsTypeService;
    @Resource
    protected CorporationsService corporationsService;
    @Resource
    protected OrderFormService orderFormService;
    @Resource
    protected WhStockOutService stockOutService;
    @Resource
    protected WhStockOutGoodsService stockOutGoodsService;
    @Resource
    protected OrderFormLogService orderFormLogService;
    @Resource
    protected WhStockInService stockInService;
    @Resource
    protected GoodsTypeComboService goodsTypeComboService;
    @Resource
    protected FreeDeliveryService freeDeliveryService;
    @Resource
    protected StoreGoodsDiscountService storeGoodsDiscountService;
    @Resource
    private RedisService redisService;

    @Resource
    private PayOkFeignService payOkFeignService;


    @ApiOperation(value = "获取门店的收货地址")
    @PostMapping(value = "/getStoreDeliveryAddress", produces = "application/json; charset=UTF-8")
    public R<Object> getStoreDeliveryAddress(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid
    ) {
        List<DeliveryAddress> list = deliveryAddressService.getByStoreUidAndStaffUid(storeUid, staffUid);
        return R.ok(list);
    }


    @ApiOperation(value = "门店的赠品购物车记录")
    @PostMapping(value = "/getGiftShopCartList", produces = "application/json; charset=UTF-8")
    public R<Object> getGiftShopCartList(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid
    ) {
        List<ShopCart> list = shopCartService.giftMainListByStoreUidAndStaffUid(storeUid, staffUid);
        return R.ok(list);
    }


    @ApiOperation(value = "赠品加入购物车")
    @PostMapping(value = "/giftAddToShopCart", produces = "application/json; charset=UTF-8")
    public R<Object> giftAddToShopCart(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "商品id") @RequestParam(value = "goodsId") Long goodsId,
            @ApiParam(value = "商品分类id") @RequestParam(value = "goodsTypeId") Long goodsTypeId,
            @ApiParam(value = "数量") @RequestParam(value = "num") Integer num,
            @ApiParam(value = "是否包邮 0.不包邮 1.包邮") @RequestParam(value = "freeDeliveryStatus") Integer freeDeliveryStatus
    ) {
        if (num <= 0)
            return R.fail("购买数量必须大于0");

        Stores stores = storesService.getByUid(storeUid);
        if (null == stores)
            return R.fail("门店信息获取失败");
        String corpUid = stores.getCorpUid();
        String storesSubjectType = stores.getSubjectType();

        Staff staff = staffService.getByUid(staffUid);
        if (staff == null)
            return R.fail("门店员工信息获取失败");

        // 轻量门店的商品折扣规则
        StoreGoodsDiscount storeGoodsDiscount = storeGoodsDiscountService.getByStoreUid(storeUid);
        Double storeGoodsDiscountRate = null;
        if (storeGoodsDiscount != null) {
            storeGoodsDiscountRate = storeGoodsDiscount.getDiscountRate();
        }

        boolean b = shopCartService.haveGiftGoodsType(storeUid, goodsId, goodsTypeId);
        if (b)
            return R.fail("已加入赠品购物车，不能重复加入");

        long cartCount = shopCartService.getStaffShopCartCount(storeUid, staffUid, 3);
        if (cartCount >= 20)
            return R.fail("赠品购物车内的商品已达到20件");

        Goods goods = goodsService.getById(goodsId);
        if (goods == null) return R.fail("商品获取失败");
        if (!goods.getEnabled().equals(1)) return R.fail("商品已下架");

        GoodsType goodsType = goodsTypeService.getByGoodsIdAndGoodsTypeId(goodsId, goodsTypeId);
        if (goodsType == null) return R.fail("商品分类获取失败");
        if (!goodsType.getEnabled().equals(1)) return R.fail("商品分类已下架");

        ShopCart data = null;
        if (goodsType.getComboType().equals(0)) {
            // 普通商品
            // 获取库存数量
            Map<Long, Integer> stockNumMap = stockInService.getStockNumMap(Arrays.asList(goodsTypeId));
            int stockNum = stockNumMap.get(goodsTypeId);
            // 根据购买记录和出库记录获取商品规格的待出库数量
            int waitSendNum = shopCartService.getWaitSendNum(goodsTypeId);

            // 判断商品和商品规格状态
            String msg = OrderFormV3Util.judgeGoodsAndGoodsType(true, goodsType.getComboType(), goods, goodsType, num, stockNum, waitSendNum);
            if (StringUtils.isNotBlank(msg))
                return R.fail(msg);

            data = ShopCartUtilV2.newShopCart(
                    goods, goodsType, corpUid, storeUid, staffUid, EnumType.ShopCartType.GIFT.getType(),
                    goodsType.getComboType(), KitUtil.getUuid(), num, headStaffUid, headStaffName,
                    freeDeliveryStatus, storeGoodsDiscountRate
            );
            shopCartService.saveOrUpdate(data);
        } else {
            // 组合商品
            // 获取组合商品的商品配置集合
            List<GoodsTypeCombo> goodsTypeComboList = goodsTypeComboService.listByMainGoodsIdAndMainGoodsTypeId(goodsId, goodsTypeId);
            if (CollectionUtils.isEmpty(goodsTypeComboList))
                return R.fail("组合商品内的商品规格获取失败");

            HashBasedTable<Long, Long, GoodsTypeCombo> table = HashBasedTable.create();
            for (GoodsTypeCombo goodsTypeCombo : goodsTypeComboList) {
                table.put(goodsTypeCombo.getGoodsTypeId(), goodsTypeCombo.getGoodsId(), goodsTypeCombo);
            }
            List<Long> childGoodsIds = new ArrayList<>(table.columnKeySet());
            List<Long> childGoodsTypeIds = new ArrayList<>(table.rowKeySet());

            List<Goods> childGoodsList = goodsService.listByIds(childGoodsIds);
            if (CollectionUtils.isEmpty(childGoodsList) || childGoodsIds.size() != childGoodsList.size())
                return R.fail("组合商品内的商品获取失败");
            List<GoodsType> childGoodsTypeList = goodsTypeService.listByIds(childGoodsTypeIds);
            if (CollectionUtils.isEmpty(childGoodsTypeList) || childGoodsTypeIds.size() != childGoodsTypeList.size())
                return R.fail("组合商品内的商品规格获取失败");

            List<Long> freeDeliveryIds = childGoodsList.stream().map(Goods::getFreeDeliveryId).collect(Collectors.toList());
            List<FreeDelivery> freeDeliveryList = freeDeliveryService.listByIds(freeDeliveryIds);
            if (CollectionUtils.isEmpty(freeDeliveryList))
                return R.fail("商品的包邮模板获取失败");
            Map<Long, FreeDelivery> freeDeliveryMap = freeDeliveryList.stream().collect(Collectors.toMap(FreeDelivery::getId, Function.identity()));

            Map<Long, Goods> childGoodsMap = childGoodsList.stream().collect(Collectors.toMap(Goods::getId, Function.identity()));
            Map<Long, GoodsType> childGoodsTypeMap = childGoodsTypeList.stream().collect(Collectors.toMap(GoodsType::getId, Function.identity()));

            for (GoodsType childGoodsType : childGoodsTypeList) {
                if (childGoodsType.getEnabled().equals(0)) {
                    Goods childGoods = childGoodsMap.get(childGoodsType.getGoodsId());
                    return R.fail("组合商品内的商品规格已下架" + childGoods.getName() + "/" + childGoodsType.getName());
                }
            }

            // 获取库存数量
            Map<Long, Integer> stockNumMap = stockInService.getStockNumMap(childGoodsTypeIds);
            // 根据购买记录和出库记录获取商品规格的待出库数量
            Map<Long, Integer> waitSendNumMap = shopCartService.getWaitSendNum(childGoodsTypeIds);

            // 新增组合商品购物车记录
            List<ShopCart> newList = new ArrayList<>();
            double totalWeight = 0;
            // 商品、组合商品规格、组合子商品，只要有一个是银行转账，主购物车记录就是银行转账
            int paymentMethod = goods.getPaymentMethod();
            String mainUid = KitUtil.getUuid();
            for (Table.Cell<Long, Long, GoodsTypeCombo> cell : table.cellSet()) {
                Long cellGoodsId = cell.getColumnKey();
                Long cellTypeIdKey = cell.getRowKey();
                GoodsTypeCombo goodsTypeCombo = cell.getValue();
                if (goodsTypeCombo == null)
                    return R.fail("组合商品的商品配置获取失败");

                Goods childGoods = childGoodsMap.get(cellGoodsId);
                GoodsType childGoodsType = childGoodsTypeMap.get(cellTypeIdKey);
                if (childGoods == null || childGoodsType == null)
                    return R.fail("组合商品内的商品未查询到");

                Integer waitSendNum = waitSendNumMap.get(goodsTypeCombo.getGoodsTypeId());
                Integer stockNum = stockNumMap.get(goodsTypeCombo.getGoodsTypeId());
                // 获取商品规格的真实可售数，库存数量减去待发货数量
                stockNum = OrderFormV3Util.getGoodsTypeNum(stockNum, waitSendNum);

                // 组合商品规定的子商品规格的购买数量
                Integer goodsTypeComboNum = goodsTypeCombo.getNum();
                // 商品规格真实购买数=购买数*组合内规定的购买数量
                int buyNum = num * goodsTypeComboNum;
                if (buyNum > stockNum)
                    return R.fail("组合商品内的商品库存数量不足，" + childGoods.getName() + "/" + childGoodsType.getName() + " 库存：" + stockNum);

                // 包含有银行转账
                if (paymentMethod == 1 && childGoods.getPaymentMethod().equals(2))
                    paymentMethod = 2;

                ShopCart childCart = ShopCartUtilV2.newChildComboShopCart(
                        childGoods, childGoodsType, corpUid, storeUid, staffUid,
                        EnumType.ShopCartType.GIFT.getType(), goodsType.getComboType(), KitUtil.getUuid(), buyNum,
                        headStaffUid, headStaffName, mainUid, goods.getId(), goods.getName(), goodsType.getId(), goodsType.getName(),
                        freeDeliveryStatus
                );

                totalWeight = DoubleUtil.sum(totalWeight, childCart.getTotalWeight());
                newList.add(childCart);
            }

            // 添加组合商品规格的购物车记录
            data = ShopCartUtilV2.newMainComboShopCart(
                    goods, goodsType, corpUid, storeUid, staffUid, EnumType.ShopCartType.GIFT.getType(),
                    goodsType.getComboType(), mainUid, num, headStaffUid, headStaffName, paymentMethod, totalWeight,
                    freeDeliveryStatus, storeGoodsDiscountRate
            );
            newList.add(0, data);

            // 新增组合商品购物车记录
            shopCartService.saveOrUpdateBatch(newList);
        }

        return R.ok(data.getId());
    }


    @ApiOperation(value = "删除赠品购物车记录")
    @PostMapping(value = "/dropShopCart", produces = "application/json; charset=UTF-8")
    public R<Object> dropShopCart(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "赠品购物车记录id") @RequestParam(value = "id") Long id
    ) {
        ShopCart shopCart = shopCartService.getById(id);
        if (shopCart == null)
            return R.fail("购物车记录获取失败");

        long l = shopCartService.dropByStoreUidAndId(storeUid, id, shopCart.getUid());
        if (l <= 0)
            return R.failDel();
        return R.ok();
    }


    @ApiOperation(value = "赠品购物车新建订单")
    @PostMapping(value = "/newOrder", produces = "application/json; charset=UTF-8")
    public R<Object> newOrder(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "门店uid") @RequestParam(value = "storeUid") String storeUid,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid") String staffUid,
            @ApiParam(value = "送货地址id") @RequestParam(value = "deliveryId") Long deliveryId,
            @ApiParam(value = "赠品凭证") @RequestParam(value = "giftImg") String giftImg,
            @ApiParam(value = "备注") @RequestParam(value = "remark", required = false) String remark
    ) throws Exception {
        Stores stores = storesService.getByUid(storeUid);
        if (null == stores)
            return R.fail("门店信息获取失败");
        String corpUid = stores.getCorpUid();
        String storeName = stores.getStoreName();

        Staff staff = staffService.getByUid(staffUid);
        if (null == staff)
            return R.fail("店长信息获取失败");

        Corporations corporations = corporationsService.getByUid(corpUid);
        if (corporations == null)
            return R.fail("公司获取失败");

        DeliveryAddress delivery = deliveryAddressService.getById(deliveryId);
        if (delivery == null)
            return R.fail("收货地址获取失败");

        // 获取赠品购物车记录
        List<ShopCart> shopCartList = shopCartService.giftMainRelationListByStoreUidAndStaffUid(storeUid, staffUid);
        if (CollectionUtils.isEmpty(shopCartList))
            return R.fail("购物车商品获取失败");
        for (ShopCart shopCart : shopCartList) {
            if (null == shopCart.getType() || !shopCart.getType().equals(3))
                return R.fail("包含非赠品购物车记录，不能操作");
        }

        // 创建订单时判断购物车是否有效
        R<ShopCartCheckDto> r = OrderFormV3Util.verifyShopCartToOrder(shopCartList, storeUid, staffUid, true, true);
        if (R.isError(r))
            return R.fail(r.getMsg());

        List<String> shopCartUids = shopCartList.stream().map(ShopCart::getUid).collect(Collectors.toList());

        ShopCartCheckDto checkDto = r.getData();
        // 订单购买的总数量
        int totalBuyNum = checkDto.getNum();
        // 订单商品总重量
        double totalWeight = checkDto.getTotalWeight();
        // 订单总金额
        double totalPrice = checkDto.getPrice();
        // 能使用代金券的总金额
        double useCouponPrice = checkDto.getUseCouponPrice();
        // 不能使用代金券的总金额
        double unUseCouponPrice = checkDto.getUnUseCouponPrice();
        // 付款方式
        int paymentMethod = checkDto.getPaymentMethod();
        // 收款公司
        int payCorp = checkDto.getPayCorp();

        // 和自营门店一样，赠品默认包邮
        List<ShopCart> cartList = checkDto.getShopCartList();
        List<ShopCart> childShopCartList = checkDto.getChildShopCartList();
        OrderFormV3Util.setFreeDelivery(cartList, childShopCartList, checkDto.getGoodsTypeMap(), 3, true);

        // 创建商品订单
        OrderForm form = new OrderForm();
        // 商品规格数量
        form.setGoodsTypeNum(shopCartUids.size());
        // 商品购买数量
        form.setBuyNum(totalBuyNum);
        // 订单商品总重量
        form.setWeight(totalWeight);
        // 价格
        form.setPrice(totalPrice);
        form.setPayPrice(0d);
        // 订单的付款方式
        form.setPaymentMethod(paymentMethod);
        // 收款公司
        form.setPayCorp(payCorp);

        String code = KitUtil.getGoodsCode();
        form.setCorpUid(corpUid);
        form.setCorpName(corporations.getCorpName());
        form.setStoreUid(storeUid);
        form.setStoreName(storeName);
        form.setStaffUid(staffUid);
        form.setStaffName(staff.getFullName());
        form.setCode(code);
        form.setGiftImg(giftImg);
        form.setProjectType(EnumType.BalanceProject.GIFT_GOODS.getType());
        form.setProjectName(EnumType.BalanceProject.GIFT_GOODS.getName());
        form.setStatus(EnumType.OrderForm.WAIT_CONFIRM.getType());
        form.setStatusName(EnumType.OrderForm.WAIT_CONFIRM.getName());
        form.setPayChannelCode(EnumType.PayChannelCode.GIFT.getType());
        form.setRemark(remark);
        form.setAddStaffUid(headStaffUid);
        form.setAddStaffName(headStaffName);
        form.setLastStaffUid(headStaffUid);
        form.setLastStaffName(headStaffName);
        // 收货地址
        form.setDeliveryId(deliveryId);
        form.setName(delivery.getName());
        form.setPhone(delivery.getPhone());
        form.setAddress(delivery.getProvinces() + delivery.getAddress());
        orderFormService.saveOrUpdate(form);
        // 更新购物车的订单信息
        shopCartService.updateFormInfo(shopCartUids, form.getCode());
        // 添加订单操作记录
        OrderFormLog log = OrderFormV3Util.newHeadLog(form.getCode(), headStaffUid, headStaffName,
                EnumType.OrderForm.WAIT_CONFIRM.getType(), "创建赠品订单，待确认", remark);
        orderFormLogService.saveOrUpdate(log);

        // 企业微信发送消息
        if (AccountUtil.isSelfStore(stores.getOperationType()) || form.getProjectType().equals(EnumType.BalanceProject.GIFT_GOODS.getType())) {
            // 企业微信获取access_token
            String accessToken = (String) redisService.get(RedisParam.QYWEINXIN_ACCESS_TOKEN);
            if (StringUtils.isBlank(accessToken)) {
                AccessTokenDto dto = QyWeiXinUtil.getAccessToken(corpid, secret);
                if (dto != null) {
                    accessToken = dto.getAccess_token();
                    int expires_in = dto.getExpires_in();
                    // redis缓存accessToken
                    redisService.set(RedisParam.QYWEINXIN_ACCESS_TOKEN, accessToken, expires_in);
                }
            }
            // 自营门店和商城赠品订单, 推送给经理和副经理
            String msg = QyWeixinMsg.confirmFreeOrderMsg(serverUrl, "赠品订单", form.getStoreName(), form.getCode());
            QyWeiXinUtil.sendToUser(accessToken, agentid, managerUserid, msg);
            QyWeiXinUtil.sendToUser(accessToken, agentid, subManagerUserid, msg);
        }
        return R.ok();
    }


    @ApiOperation(value = "修改送货地址")
    @PostMapping(value = "/editAddress", produces = "application/json; charset=UTF-8")
    public R<Object> editAddress(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "订单号") @RequestParam(value = "code") String code,
            @ApiParam(value = "送货地址id") @RequestParam(value = "deliveryId") Long deliveryId
    ) {
        OrderForm form = orderFormService.getByCode(null, code);
        if (form == null) return R.fail("订单获取失败");

        DeliveryAddress delivery = deliveryAddressService.getById(deliveryId);
        if (delivery == null) return R.fail("收货地址获取失败");

        boolean l = orderFormService.updateAddress(form.getStaffUid(), code, delivery);
        if (!l)
            return R.fail("修改失败！订单状态：" + EnumType.OrderForm.getStatus(form.getStatus()));

        return R.ok();
    }


    @GlobalTransactional
    @ApiOperation(value = "赠品订单-确认通过")
    @PostMapping(value = "/confirm", produces = "application/json; charset=UTF-8")
    public R<Object> confirm(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "订单号") @RequestParam(value = "code") String code,
            @ApiParam(value = "赠品凭证") @RequestParam(value = "giftImg", required = false) String giftImg,
            @ApiParam(value = "备注") @RequestParam(value = "remark", required = false) String remark
    ) throws Exception {
        // 查询充值订单流水号
        OrderForm form = orderFormService.getByCode(null, code);
        if (form == null)
            return R.fail("获取订单失败");
        if (EnumType.BalanceProject.GIFT_GOODS.getType() != form.getProjectType())
            return R.fail("不是赠品商品订单");
        if (!code.startsWith(EnumType.CodeCategory.TOB.getType()))
            return R.fail("非toB订单不能支付");

        // 验证订单有效性
        String msg = OrderFormV3Util.verifyOrderForm(form, false, true);
        if (StringUtils.isNotBlank(msg))
            return R.fail(msg);

        // 订单支付成功后的处理
        String resultMsg = payOkFeignService.giftGoodsOrder(headStaffUid, headStaffName, code, StringUtils.isNotBlank(remark) ? remark : "");
        if (StringUtils.isNotBlank(resultMsg))
            return R.fail(resultMsg);

        return R.ok();
    }


    @ApiOperation(value = "赠品订单-删除订单")
    @PostMapping(value = "/delete", produces = "application/json; charset=UTF-8")
    public R<Object> delete(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "订单号") @RequestParam(value = "code") String code
    ) {
        OrderForm form = orderFormService.getByCode(null, code);
        if (form == null) return R.fail("获取订单失败");

        long l = orderFormService.deleteByStaffIdAndCode(form.getStaffUid(), code);
        if (l <= 0)
            return R.fail("删除失败！订单状态：" + EnumType.OrderForm.getStatus(form.getStatus()));

        shopCartService.deleteByStaffIdAndCode(form.getStaffUid(), code);
        return R.ok();
    }

    @Transactional(rollbackFor = DescribeException.class)
    @ApiOperation(value = "赠品订单-撤回订单")
    @PostMapping(value = "/revocation", produces = "application/json; charset=UTF-8")
    public R<Object> revocation(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "订单号") @RequestParam(value = "code") String code,
            @ApiParam(value = "备注") @RequestParam(value = "remark", required = false) String remark
    ) throws Exception {
        if (StringUtils.isBlank(remark))
            return R.fail("请填写备注备注");

        // 查询充值订单流水号
        OrderForm form = orderFormService.getByCode(null, code);
        if (null == form)
            return R.fail("订单获取失败");
        if (!form.getStatus().equals(EnumType.OrderForm.WAIT_SEND.getType()))
            return R.fail("订单状态不符合");

        Stores stores = storesService.getByUid(form.getStoreUid());
        if (null == stores)
            return R.fail("门店信息获取失败");

        if (!form.getProjectType().equals(EnumType.BalanceProject.GIFT_GOODS.getType()) &&
                !(form.getProjectType().equals(EnumType.BalanceProject.BUY_GOODS.getType()) && AccountUtil.isSelfStore(stores.getOperationType())))
            return R.fail("不是赠品订单或自营门店订单");

        OrderFormLog formLog = orderFormLogService.getByCodeAndStatus(code, EnumType.OrderForm.WAIT_SEND.getType());
        if (null == formLog)
            return R.fail("下单日志记录获取失败");

        // 超过30天不能修改
        if (TimeUtil.moreThanDay(formLog.getAddTime(), 30))
            return R.fail("审核通过已超过30天，不能撤回");

        // 判断商品发货情况
        long outLCnt = stockOutService.getOkOutCnt(code);
        if (outLCnt > 0)
            return R.fail("已经开始发货，不能撤回");

        // 商品数据
        List<ShopCart> shopCartList = shopCartService.getByCode(form.getStaffUid(), code);
        if (CollectionUtils.isEmpty(shopCartList))
            return R.fail("订单的购物车记录获取失败");
        List<Long> goodsTypeIds = shopCartList.stream().map(ShopCart::getGoodsTypeId).collect(Collectors.toList());
        List<GoodsType> goodsTypeList = goodsTypeService.listByIds(goodsTypeIds);
        if (CollectionUtils.isEmpty(goodsTypeList) || shopCartList.size() != goodsTypeList.size())
            return R.fail("订单内的商品规格不存在或缺失");

        // 撤回已通过订单
        boolean l = orderFormService.revocationGiftOrder(code, headStaffUid, headStaffName);
        if (!l) return R.fail("赠品订单，取消失败");

        // 撤回处理购物车记录
        l = shopCartService.revocationGiftShopCarts(code, headStaffUid, headStaffName);
        if (!l) throw new DescribeException("赠品购物车记录，取消失败");

        // 删除保存中的出库订单
        stockOutService.dropSaveOuts(code);
        // 删除保存中的出库商品详情
        stockOutGoodsService.dropSaveOutGoods(code);

        // 添加订单操作记录
        OrderFormLog log = OrderFormV3Util.newHeadLog(form.getCode(), headStaffUid, headStaffName,
                EnumType.OrderForm.REVOCATION_GIFT.getType(), "撤回已通过的赠品订单", remark);
        orderFormLogService.saveOrUpdate(log);

        return R.ok();
    }


    @ApiOperation(value = "上传赠品凭证")
    @PostMapping(value = "/uploadGiftImg", produces = "application/json; charset=UTF-8")
    public R<Object> uploadGiftImg(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "图片文件") @RequestPart(value = "file") MultipartFile file
    ) throws Exception {
        // 上传图片到服务器
        R<String> r = LocalFileUtil.uploadImg(LocalFileUtil.orderFormBaseDir, file);
        if (R.isError(r))
            return R.fail(r.getMsg());

        String imageUrl = r.getData();

        return R.ok(imageUrl);
    }

}
